package com.quyang.voice.utils.xinsheng.request.form;


import com.alibaba.fastjson.JSONObject;
import com.quyang.voice.utils.xinsheng.constants.NcountKey;
import lombok.Data;
import org.apache.commons.lang3.StringUtils;

import java.io.Serializable;
import java.lang.reflect.Field;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;


/**
 * 交易报文
 * 交易报文是面向商户的，各交易报文中的字段必须与商户提交请求中的参数key一致
 * <p>Title: BaseTransForm</p>
 * <p>Description: </p>
 * <p>Company: </p>
 */
@Data
public abstract class BaseTransForm implements Serializable{

	private static final long serialVersionUID = 1L;

    public static final String VERSION = "version";
    public static final String TRAN_CODE = "tranCode";
    public static final String MER_ID = "merId";
    public static final String MER_ORDER_ID = "merOrderId";
    public static final String CHARSET = "charset";
    public static final String SIGN_TYPE = "signType";
    public static final String SIGN_VALUE = "signValue";
    public static final String MER_ATTACH = "merAttach";
	public static final String SUBMIT_TIME = "submitTime";
	public static final String MSG_CIPHER_TEXT = "msgCiphertext";
	public static final String RESULT_CODE = "resultCode";
	public static final String ERROR_CODE = "errorCode";
	public static final String ERROR_MSG = "errorMsg";

	// 暂定公共的报文字段
	protected String tranCode;
	protected String version;
	protected String merId;
	protected String merOrderId;
	protected String signType;
	protected String signValue;
	protected String msgCiphertext;
	protected String charset;
	protected String merAttach;
	protected String submitTime;

	//提交地址
	protected String submitUrl;

	/**
	 * 获取公共返回参数<br>
	 * Map中的key必须与返回XML文件中的field的name值一致<br>
	 * 子类可选择性重写
	 * @return
	 */
	@SuppressWarnings("static-access")
	public Map<String, Object> getCommonRespParams() {
		Map<String, Object> commonParams = new HashMap<String, Object>();
		commonParams.put(this.VERSION, this.version);
		commonParams.put(this.TRAN_CODE, this.tranCode);
		commonParams.put(this.MER_ORDER_ID, this.merOrderId);
		commonParams.put(this.MER_ID, this.merId);
		commonParams.put(this.MER_ATTACH, this.merAttach);
		commonParams.put(this.CHARSET, this.charset);
		commonParams.put(this.SIGN_TYPE, this.signType);
		return commonParams;
	}

	/**
	 * 获取共用请求的签名字段
	 * @author wgy
	 * @date 2018年8月10日 上午10:26:54
	 * @description 一句话描述功能
	 * @return Map<String,Object>
	 */
	@SuppressWarnings("static-access")
	public Map<String,Object> getCommonReqSignParams(){
		Map<String, Object> commonParams = new HashMap<String, Object>();
		commonParams.put(this.TRAN_CODE, this.tranCode);
		commonParams.put(this.VERSION, this.version);
		commonParams.put(this.MER_ID, this.merId);
		commonParams.put(this.MER_ORDER_ID, this.merOrderId);
		commonParams.put(this.SUBMIT_TIME, this.submitTime);
		commonParams.put(this.MSG_CIPHER_TEXT, this.msgCiphertext);
		commonParams.put(this.SIGN_TYPE, this.signType);
		return commonParams;
	}

	/**
	 * 获取加密json串明文
	 * @author wgy
	 * @date 2018年8月27日 下午6:08:46
	 * @description 一句话描述功能
	 * @return String
	 */
	public abstract String getEncryptJsonStr();

	/**
	 * 获取验签字段
	 * @return
	 */
	public abstract String getVerifyJsonStr();

	/**
	 * 获取提交字段
	 * @return
	 */
	public abstract String getSubmitJsonStr();



	public void initCommonParams(String tranCode) {
		DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
		String format = LocalDateTime.now().format(dateTimeFormatter);

		this.version="1.0";
		this.tranCode=tranCode;
		this.merId= NcountKey.MER_ID;
		this.merOrderId=tranCode+"_"+ format;
//		this.merOrderId = "T007_20210316165453";
		this.submitTime= format;
		this.signType="1";
		this.merAttach="";
		this.charset="UTF-8";
	}

	public void initCommonParams(String tranCode,String merOrderId) {
		DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
		String format = LocalDateTime.now().format(dateTimeFormatter);

		this.version="1.0";
		this.tranCode=tranCode;
		this.merId= NcountKey.MER_ID;
		if(StringUtils.isNotBlank(merOrderId)){
			this.merOrderId = merOrderId;
		}else{
			this.merOrderId=tranCode+"_"+ format;
		}
		this.submitTime= format;
		this.signType="1";
		this.merAttach="";
		this.charset="UTF-8";
	}

	public String getCommonSignStr() {
		StringBuffer sb = new StringBuffer();
		sb.append(this.VERSION);
		sb.append("=[");
		sb.append(getVersion());
		sb.append("]");

		sb.append(this.TRAN_CODE);
		sb.append("=[");
		sb.append(getTranCode());
		sb.append("]");

		sb.append(this.MER_ID);
		sb.append("=[");
		sb.append(getMerId());
		sb.append("]");

		sb.append(this.MER_ORDER_ID);
		sb.append("=[");
		sb.append(getMerOrderId());
		sb.append("]");

		sb.append(this.SUBMIT_TIME);
		sb.append("=[");
		sb.append(getSubmitTime());
		sb.append("]");

		sb.append(this.MSG_CIPHER_TEXT);
		sb.append("=[");
		sb.append(getMsgCiphertext());
		sb.append("]");

		sb.append(this.SIGN_TYPE);
		sb.append("=[");
		sb.append(getSignType());
		sb.append("]");

		return sb.toString();
	}

	public String getValueByReflet(Object model, String paraName){
		// 返回值
		String value = "";
		try {
			// 获取属性值
			Field[] fields = model.getClass().getDeclaredFields();

			for (Field field : fields) {
				field.setAccessible(true);

				if (field.getName().equals(paraName)) {
					value = (String) field.get(model);

					break;
				}
			}
		}catch (Exception e){

		}
		return value;
	}

	public String getJsonStr(Object model,String[] strArr) {
		JSONObject json = new JSONObject(true);
		for(String file:strArr){
			json.put(file, getValueByReflet(model,file));
		}
		return json.toJSONString();
	}

}
